package com.ltxtiyu.video.tool;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;


public class Uploader {
    private static Logger LOGGER = LoggerFactory.getLogger(Uploader.class);
    private MultipartHttpServletRequest request = null;
    private HashMap<String, String> errorInfo = new HashMap<String, String>();
    /**
     * 原始文件名
     */
    private String originalName;
    /**
     * 上传的文件名
     */
    private String fileName = "";
    /**
     * 文件大小
     */
    private String size;
    /**
     * 文件描述
     */
    private String title;
    /**
     * 文件类型
     */
    private String type;
    /**
     * 输出URL
     */
    private String url;
    /**
     * 状态
     */
    private String state = "";

    /**
     * 默认限制大小,单位为KB
     */
    private int maxSize = 10000;
    /**
     * 默认上传目录
     */
    private String savePath = "upload";
    /**
     * 文件允许格式
     */
    private String[] allowFiles = {".rar", ".doc", ".docx", ".zip", ".pdf", ".txt", ".swf", ".wmv", ".gif", ".png", ".jpg", ".jpeg", ".bmp"};

    /**
     * contentType 阿里云上传使用
     */
    private String contentType = "";

    public Uploader(MultipartHttpServletRequest request) {
        this.request = request;
        HashMap<String, String> tmp = this.errorInfo;
        tmp.put("SUCCESS", "SUCCESS");
        tmp.put("NOFILE", "未包含文件上传域");
        tmp.put("TYPE", "不允许的文件格式");
        tmp.put("SIZE", "文件大小超出限制");
        tmp.put("ENTYPE", "请求类型ENTYPE错误");
        tmp.put("REQUEST", "上传请求异常");
        tmp.put("IO", "IO异常");
        tmp.put("DIR", "目录创建失败");
        tmp.put("UNKNOWN", "未知错误");
    }

    public void upload() {
        String uploadPath = DateUtil.toStringXiumaDate(new Date());
        String path = getFileUrl(uploadPath);
        Iterator<String> itr = request.getFileNames();
        MultipartFile mpf = null;
        String ext = "";
        while (itr.hasNext()) {
            mpf = request.getFile(itr.next());
            this.originalName = mpf.getOriginalFilename();
            ext = getFileExt(originalName);
            if (!StringTool.isNotBlank(title)) {
                this.title = originalName;
            }
            // 验证文件类型
            if (!checkFileType(ext)) {
                break;
            }
            // 验证文件大小
            if (checkFileMaxSize(mpf.getSize())) {
                break;
            }

            LOGGER.info(mpf.getOriginalFilename() + " uploaded! " + " ext:" + ext);
            String fileName = getName(originalName);
            String fileSavePath = path + "/" + fileName;
            this.url = savePath + "/" + uploadPath + "/" + fileName;
            try {
                File file = new File(path);
                if (!file.isFile()) {
                    file.mkdirs();
                }
                FileCopyUtils.copy(mpf.getBytes(), new FileOutputStream(fileSavePath));
                this.contentType = JMineUtil.getMine(fileSavePath);
                this.state = this.errorInfo.get("SUCCESS");
            } catch (IOException e) {
                this.state = this.errorInfo.get("IO");
                LOGGER.error("上传文件出错", e);
            }
        }
    }

    public String getTempPath() {
        String classPath = this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
        if ((classPath.indexOf("file:") > -1) && (classPath.indexOf(".jar") > -1)) {
            classPath = classPath.substring(classPath.indexOf("file:") + 5);
            classPath = classPath.substring(0, classPath.indexOf(".jar"));
            if (classPath.indexOf("/") > -1) {
                classPath = classPath.substring(0, classPath.lastIndexOf("/") + 1);
            }
        }else{
            classPath=request.getSession().getServletContext().getRealPath("/" );
        }
        return classPath;
    }

    private String getFileUrl(String customPath) {
        /*String realPath = getTempPath();
        realPath += savePath + "/" + customPath;

        LOGGER.error(realPath);
        return realPath;*/
        return request.getSession().getServletContext().getRealPath(savePath + "/" + customPath);
    }

    /**
     * 文件类型判断
     *
     * @return
     */
    private boolean checkFileType(String originaExt) {
        Iterator<String> type = Arrays.asList(this.allowFiles).iterator();
        while (type.hasNext()) {
            String ext = type.next();
            if (originaExt.toLowerCase().endsWith(ext)) {
                return true;
            }
        }
        this.state = this.errorInfo.get("TYPE");
        return false;
    }

    private boolean checkFileMaxSize(long originaSize) {
        this.size = String.valueOf(originaSize / 1024);
        if (Integer.valueOf(size) > maxSize) {
            return true;
        }
        this.state = this.errorInfo.get("SIZE");
        return false;
    }

    /**
     * 获取文件扩展名
     *
     * @return string
     */
    private String getFileExt(String originalName) {
        return this.type = originalName.substring(originalName.lastIndexOf("."));
    }

    /**
     * 依据原始文件名生成新文件名
     *
     * @return
     */
    private String getName(String originalName) {
        Random random = new Random();
        return this.fileName = "" + random.nextInt(10000) + System.currentTimeMillis() + this.getFileExt(originalName);
    }

    /**
     * 限制文件大小，以KB为单位
     *
     * @return
     */
    public int getMaxSize() {
        return maxSize;
    }

    /**
     * 限制文件大小，以KB为单位
     */
    public void setMaxSize(int maxSize) {
        this.maxSize = maxSize;
    }

    /**
     * 文件上传存放目录，默认为upload
     *
     * @return
     */
    public String getSavePath() {
        return savePath;
    }

    /**
     * 文件上传存放目录，默认为upload
     */
    public void setSavePath(String savePath) {
        this.savePath = savePath;
    }

    /**
     * 文件上传限制类型，默认为".rar", ".doc", ".docx", ".zip", ".pdf", ".txt", ".swf",
     * ".wmv", ".gif", ".png", ".jpg", ".jpeg", ".bmp"
     *
     * @return
     */
    public String[] getAllowFiles() {
        return allowFiles;
    }

    /**
     * 文件上传限制类型，默认为".rar", ".doc", ".docx", ".zip", ".pdf", ".txt", ".swf",
     * ".wmv", ".gif", ".png", ".jpg", ".jpeg", ".bmp"
     */
    public void setAllowFiles(String[] allowFiles) {
        this.allowFiles = allowFiles;
    }

    /**
     * 获取原始文件名
     *
     * @return
     */
    public String getOriginalName() {
        return originalName;
    }

    /**
     * 获取新文件名
     *
     * @return
     */
    public String getFileName() {
        return fileName;
    }

    /**
     * 获取文件大小
     *
     * @return
     */
    public String getSize() {
        return size;
    }

    /**
     * 获取文件描述
     *
     * @return
     */
    public String getTitle() {
        return title;
    }

    /**
     * 获取文件类型
     *
     * @return
     */
    public String getType() {
        return type;
    }

    /**
     * 获取文件存放路径
     *
     * @return
     */
    public String getUrl() {
        return url;
    }

    /**
     * 获取上传状态
     *
     * @return
     */
    public String getState() {
        return state;
    }

    /**
     * 获取mime类型
     *
     * @return
     */
    public String getContentType() {
        return contentType;
    }


}
